Strict
Import mojo
Import agfx

' ***********************************************************************************
' 2D VECTOR MATH 
' ***********************************************************************************

'|-----------------------------------------------------------------------------------
'| ADD
'|-----------------------------------------------------------------------------------
Function VecAdd:TVector2(a:TVector2,b:TVector2)
	
	Local v:TVector2 = New TVector2(0,0)
	
	v.x = a.x + b.x
	v.y = a.y + b.y 
	
	Return v
	
End Function

'|-----------------------------------------------------------------------------------
'| SUB
'|-----------------------------------------------------------------------------------
Function VecSub:TVector2(a:TVector2,b:TVector2)
	
	Local v:TVector2 = New TVector2(0,0)
	
	v.x = a.x - b.x
	v.y = a.y - b.y 
	
	Return v
	
End Function

'|-----------------------------------------------------------------------------------
'| DIV v*f
'|-----------------------------------------------------------------------------------
Function VecDiv:TVector2(a:TVector2,f:Float)
	
	Local v:TVector2 = New TVector2(0,0)
	v.x = a.x/f
	v.y = a.y/f
	
	Return v
	
End Function

'|-----------------------------------------------------------------------------------
'| DIV v1/v2
'|-----------------------------------------------------------------------------------
Function VecDiv:TVector2(v1:TVector2,v2:TVector2)
	
	Return New TVector2(v1.x/v2.x,v1.y/v2.y)
	
End Function

'|-----------------------------------------------------------------------------------
'| MULT v1*v2
'|-----------------------------------------------------------------------------------
Function VecMult:TVector2(a:TVector2,b:TVector2)
	
	Return New TVector2(a.x*b.x,a.y*b.y)
	
End Function

'|-----------------------------------------------------------------------------------
'| MULT v1*f
'|-----------------------------------------------------------------------------------
Function VecMult:TVector2(a:TVector2,f:Float)
	
	Local v:TVector2 = New TVector2(0,0)
	
	v.x = a.x*f
	v.y = a.y*f
	
	Return v
	
End Function

'|-----------------------------------------------------------------------------------
'| DOT
'|-----------------------------------------------------------------------------------
Function VecDot:Float(a:TVector2,b:TVector2)
	
	Return ( a.x * b.x + a.y * b.y)
	
End Function

'|-----------------------------------------------------------------------------------
'| Get Left Normal
'|-----------------------------------------------------------------------------------
Function VecLeftNormal:TVector2(a:TVector2)
	
	Local v:TVector2 = New TVector2(a.y,-a.x)	
	Return VecNormalize(v)
	
End Function

'|-----------------------------------------------------------------------------------
'| Get Right Normal
'|-----------------------------------------------------------------------------------
Function VecRightNormal:TVector2(a:TVector2)
	
	Local v:TVector2 = New TVector2(-a.y,a.x)	
	Return VecNormalize(v)
	
End Function

'|-----------------------------------------------------------------------------------
'| DISTANCE
'|-----------------------------------------------------------------------------------
Function VecDist:Float(a:TVector2,b:TVector2)
	
	
	Local dx:Float = a.x - b.x 
	Local dy:Float = a.y - b.y 
	
	Return Sqrt( dx*dx + dy*dy ) 	
	
End Function

'|-----------------------------------------------------------------------------------
'| Length
'|-----------------------------------------------------------------------------------
Function VecLength:Float(a:TVector2)
	
	Return Sqrt( a.x*a.x + a.y*a.y )
	
End Function

'|-----------------------------------------------------------------------------------
'| ANGLE
'|-----------------------------------------------------------------------------------
Function VecAngle:Float(a:TVector2,b:TVector2)

		
		Local dot:Float = VecDot(a,b)

		Local combinedLength:Float = VecLength(a)*VecLength(a)
		
		If combinedLength = 0 Then Return 0
		
		Local quaski:Float = dot/combinedLength
		
		Local angle:Float = ACos( quaski )
		
		Return angle
	
End

Function VecAngleToAntiClockwise:Float( from:TVector2,target:TVector2 )
	Local angle:Float = ATan2(-from.y , from.x)  - ATan2(-target.y , target.x)
	If angle < 0 Then angle += 360
	If angle >= 360 Then angle -= 360
	Return angle		
End

Function VecAngleToClockwise:Float( from:TVector2,target:TVector2 )
	Local angle:Float =  VecAngleToAntiClockwise(from,target)-360
	Return -angle
End
'|-----------------------------------------------------------------------------------
'| NORMALIZE
'|-----------------------------------------------------------------------------------
Function VecNormalize:TVector2(a:TVector2)
	
	Return VecNormalize(a.x,a.y)
End

Function VecNormalize:TVector2(x:Float,y:Float)
	
	Local v:TVector2 = New TVector2(x,y)
	Local Length:Float = 1.0/VecLength(v)
	
	If Length = 0.0 Then
			Return v
	EndIf
	
	v.x = x * Length
	v.y = y * Length
	
	Return v
End

'|-----------------------------------------------------------------------------------
'| ROTATE
'|-----------------------------------------------------------------------------------
Function VecRotate:TVector2(a:TVector2,angle:Float)
	Local v:TVector2 = New TVector2(0,0)
	
	v.x = a.x*Cos(angle) - a.y*Sin(angle)
	v.y = a.y*Cos(angle) + a.x*Sin(angle)
	
	Return v
End

'|-----------------------------------------------------------------------------------
'| NORMALIZED DIRECTION
'|-----------------------------------------------------------------------------------
Function VecDirection:TVector2(a:TVector2,b:TVector2)

	Local v:TVector2 = VecNormalize(VecSub(b,a))	
	Return v
End


